﻿using System;
using System.Xml.Serialization;

using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.Common.Utilities;
using Fuse8.DomainFramework.BusinessService;

namespace Fuse8.ContentManagementFramework.Domain
{
    public partial class CmsUser
    {        
        #region Constructor

        public CmsUser(string loginName)
            : base()
        {
            Guard.ArgumentNotEmpty(loginName, "loginName");

            var user = new BusinessServiceFacade<CmsUser, int>().FindOne(p => p.LoginName == loginName);

            if (user != null)
            {
                Id = user.Id;
                Firstname = user.Firstname;
                Lastname = user.Lastname;
                UserEmail = user.UserEmail;
                LoginName = user.LoginName;
                SiteId = user.SiteId;
                SiteGroupId = user.SiteGroupId;
                PasswordSalt = user.PasswordSalt;
                PasswordHash = user.PasswordHash;
                IsEnabled = user.IsEnabled;
                IsSystem = user.IsSystem;
                CreatedBy = user.CreatedBy;
                DateCreated = user.DateCreated;
                LastUpdatedBy = user.LastUpdatedBy;
                DateLastUpdated = user.DateLastUpdated;
            }
            else
            {
                //TO DO
                throw new ArgumentNullException();
            }
        }

        #endregion

        #region Properties

        [XmlIgnore]
        public string UserCreatedBy { get; set; }

        [XmlIgnore]
        public string UserLastUpdatedBy { get; set; }

        [XmlIgnore]
        public string PlainPassword { get; internal set; }

        [XmlIgnore]
        public bool HasInitialPassword { get; set; }

        [XmlIgnore]
        public string PasswordHash { get; set; }

        [XmlIgnore]
        public string PasswordSalt { get; set; }

        public string UserName { get { return string.Format("{0} {1}", Firstname, Lastname).Trim(); } }

        #endregion

        #region Methods

        public bool Validate(string password, int passwordHistoryDepth)
        {
            Guard.ArgumentNotEmpty(password, "password");

            return HashUtility.ValidatePassword(
                PasswordHash,
                passwordHistoryDepth > 0 ?
                HashUtility.CreatePasswordHash(password) :
                    HashUtility.CreatePasswordHash(password, PasswordSalt));
        }

        public void StorePassword(string password, int passwordHistoryDepth)
        {
            Guard.ArgumentNotEmpty(password, "password");

            PlainPassword = password;

            if (passwordHistoryDepth > 0)
            {
                PasswordHash = HashUtility.CreatePasswordHash(password);
            }
            else
            {
                if (PasswordSalt == null)
                {
                    PasswordSalt = HashUtility.CreateSalt();
                }

                PasswordHash = HashUtility.CreatePasswordHash(password, PasswordSalt);
            }
        }

        #endregion
    }
}
